
package l1j.server.server.clientpackets;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.ArrayList;
import java.util.List;

import l1j.server.echo.ClientThread;
import l1j.server.server.ActionCodes;
import l1j.server.server.model.L1PolyMorph;
import l1j.server.server.model.Instance.L1ItemInstance;
import l1j.server.server.model.Instance.L1NpcInstance;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.model.Instance.L1PetInstance;
import l1j.server.server.serverpackets.S_DoActionGFX;
import l1j.server.server.serverpackets.S_DoActionShop;
import l1j.server.server.serverpackets.S_ServerMessage;
import l1j.server.server.templates.L1PrivateShopBuyList;
import l1j.server.server.templates.L1PrivateShopSellList;
import static l1j.server.server.model.skill.L1SkillId.擺攤延遲;
/**
 * 處理收到由客戶端傳來商店的封包
 */
public class C_Shop extends ClientBasePacket {

	private static final String C_SHOP = "[C] C_Shop";
	private static final Logger _log = Logger.getLogger(C_Shop.class.getName());
	@Override
	public String getType() {
		return C_SHOP;
	}

	/**
	 * 『來源:客戶端』<位址:38>{長度:36}(時間:-465193548)
        0000: 26 00 01 00 d4 b3 75 00 05 00 00 00 01 00 00 00 &.....u.........
        0010: 00 00 35 35 ff 00 74 72 61 64 65 7a 6f 6e 65 31 ..55..tradezone1
        0020: 00 08 50 57 ..PW
	 */
	@Override
	public void start(final byte[] decrypt, final ClientThread client) {
		try {
			// 資料載入
			this.read(decrypt);
			final L1PcInstance pc = client.getActiveChar();
			if (pc == null || pc.isGhost()) {
				return;
			}
			if(pc.hasSkillEffect(擺攤延遲)){
				return;
			}
			pc.setSkillEffect(擺攤延遲, 3000);

			final int mapId = pc.getMapId();
			if (mapId != 340 && mapId != 350 && mapId != 360 && mapId != 370) {
				pc.sendPackets(new S_ServerMessage(876)); // この場所では個人商店を開けません。
				return;
			}

			final List<L1PrivateShopSellList> sellList = pc.getSellList();
			final List<L1PrivateShopBuyList> buyList = pc.getBuyList();
			L1ItemInstance checkItem;
			boolean tradable = true;

			final int type = this.readC();
			if (type == 0) { // 開始
				final int sellTotalCount = this.readH();
				int sellObjectId;
				int sellPrice;
				int sellCount;
				final ArrayList<Integer> item = new ArrayList<Integer>();

				for (int i = 0; i < sellTotalCount; i++) {
					sellObjectId = this.readD();
					sellPrice = this.readD();
					sellCount = this.readD();

					//opqlo 防洗
					sellCount = Math.abs(sellCount);
					sellCount = Math.min(sellCount,2000000000);
					sellCount = Math.max(sellCount,0);
					//opqlo 防洗


					// 取引可能なアイテムかチェック
					checkItem = pc.getInventory().getItem(sellObjectId);
					if (!checkItem.getItem().isTradable()) {
						tradable = false;
						pc.sendPackets(new S_ServerMessage(166, checkItem.getItem().getName(), "無法交易。"));// \f1%0が%4%1%3%2
					}
					if (checkItem.getBless() >= 128) { // opqlo封印的裝備無法擺上商店

						pc.sendPackets(new S_ServerMessage(210, checkItem.getItem().getName()));
						return;
					}
					if (checkItem.getDeleteDate() != null) { //opqlo 道具天數刪除系統(無法擺商店)
						pc.sendPackets(new S_ServerMessage(166, checkItem.getName(), " 無法交易"));
						return;
					}
					// opqlo 防止異常堆疊交易
					if (checkItem.getCount() > 1 && checkItem.getItem().isStackable() == false) {
						pc.sendPackets(new S_ServerMessage(166,"此物品非堆疊，但異常堆疊無法交易"));
						return;
					}
					// opqlo 支票、商城元寶 不得擺攤
					if(checkItem.getItemId() == 90308 || checkItem.getItemId() == 60308){
						pc.sendPackets(new S_ServerMessage(166, checkItem.getName(), " 無法販售"));
						return;
					}

					for (final L1NpcInstance petNpc : pc.getPetList().values()) {
						if (petNpc instanceof L1PetInstance) {
							final L1PetInstance pet = (L1PetInstance) petNpc;
							if (checkItem.getId() == pet.getItemObjId()) {
								tradable = false;
								// \f1%0は捨てたりまたは他人に讓ることができません。
								pc.sendPackets(new S_ServerMessage(210, checkItem.getItem().getName()));
								break;
							}
						}
					}
					//TODO 魔法娃娃使用判斷
			/*		for (final L1DollInstance doll : pc.getDollList().values()) {
						if (checkItem.getId() == doll.getItemObjId()) {
							tradable = false;
							pc.sendPackets(new S_ServerMessage(1181));
							break;
						}
					}*/
					if(pc.getDollList().getDollByItem(checkItem.getId()) !=null){
						pc.sendPackets(new S_ServerMessage(1181));
						tradable = false;
						break;
					}
					if(item.contains(sellObjectId)){
						pc.sendPackets(new S_ServerMessage(166,"物品異常無法交易"));
						tradable = false;
						break;
					}
					final L1PrivateShopSellList pssl = new L1PrivateShopSellList();
					pssl.setItemObjectId(sellObjectId);
					pssl.setSellPrice(sellPrice);
					pssl.setSellTotalCount(sellCount);
					sellList.add(pssl);

				}
				item.clear();
				final int buyTotalCount = this.readH();
				int buyObjectId;
				int buyPrice;
				int buyCount;
				for (int i = 0; i < buyTotalCount; i++) {
					buyObjectId = this.readD();
					buyPrice = this.readD();
					buyCount = this.readD();

					//opqlo 防洗
					buyCount = Math.abs(buyCount);
					buyCount = Math.min(buyCount,2000000000);
					buyCount = Math.max(buyCount,0);
					//opqlo 防洗

					// 取引可能なアイテムかチェック
					checkItem = pc.getInventory().getItem(buyObjectId);
					if(checkItem == null){
						tradable = false;
						break;
					}
					if (!checkItem.getItem().isTradable()) {
						tradable = false;
						pc.sendPackets(new S_ServerMessage(166, checkItem.getItem().getName(), "無法交易。"));// \f1%0が%4%1%3%2
					}
					if (checkItem.getBless() >= 128) { // opqlo封印的裝備無法擺上商店

						pc.sendPackets(new S_ServerMessage(210, checkItem.getItem().getName()));
						return;
					}
					if (checkItem.getDeleteDate() != null) { //opqlo 道具天數刪除系統(無法擺商店)
						pc.sendPackets(new S_ServerMessage(166, checkItem.getName(), " 無法交易"));
						return;
					}
					// opqlo 防止異常堆疊交易
					if (checkItem.getCount() > 1 && checkItem.getItem().isStackable() == false) {
						pc.sendPackets(new S_ServerMessage(166,"此物品非堆疊，但異常堆疊無法交易"));
						return;
					}
					// opqlo 支票、商城元寶 不得擺攤
					if(checkItem.getItemId() == 90308 || checkItem.getItemId() == 60308){
						pc.sendPackets(new S_ServerMessage(166, checkItem.getName(), " 無法收購"));
						return;
					}


					for (final L1NpcInstance petNpc : pc.getPetList().values()) {
						if (petNpc instanceof L1PetInstance) {
							final L1PetInstance pet = (L1PetInstance) petNpc;
							if (checkItem.getId() == pet.getItemObjId()) {
								tradable = false;
								// \f1%0は捨てたりまたは他人に讓ることができません。
								pc.sendPackets(new S_ServerMessage(210, checkItem.getItem().getName()));
								break;
							}
						}
					}
					//TODO 魔法娃娃使用判斷
					/*for (final L1DollInstance doll : pc.getDollList().values()) {
						if (checkItem.getId() == doll.getItemObjId()) {
							tradable = false;
							pc.sendPackets(new S_ServerMessage(1181));
							break;
						}
					}*/
					if(pc.getDollList().getDollByItem(checkItem.getId()) !=null){
						pc.sendPackets(new S_ServerMessage(1181));
						tradable = false;
						break;
					}
					if(item.contains(buyObjectId)){
						pc.sendPackets(new S_ServerMessage(166,"物品異常無法交易"));
						tradable = false;
						break;
					}
					final L1PrivateShopBuyList psbl = new L1PrivateShopBuyList();
					psbl.setItemObjectId(buyObjectId);
					psbl.setBuyPrice(buyPrice);
					psbl.setBuyTotalCount(buyCount);
					buyList.add(psbl);
				}
				if (!tradable) { // 取引不可能なアイテムが含まれている場合、個人商店終了
					sellList.clear();
					buyList.clear();
					pc.setPrivateShop(false);
					pc.sendPackets(new S_DoActionGFX(pc.getId(),ActionCodes.ACTION_Idle));
					pc.broadcastPacketAll(new S_DoActionGFX(pc.getId(),ActionCodes.ACTION_Idle));
					return;
				}
				final byte[] chat = this.readByte();
				pc.setShopChat(chat);
				pc.setPrivateShop(true);
				L1PolyMorph.undoPoly(pc);
				pc.sendPackets(new S_DoActionShop(pc.getId(),ActionCodes.ACTION_Shop, chat));
				pc.broadcastPacketAll(new S_DoActionShop(pc.getId(),ActionCodes.ACTION_Shop, chat));
			} else if (type == 1) { // 終了
				sellList.clear();
				buyList.clear();
				pc.setPrivateShop(false);
				pc.sendPackets(new S_DoActionGFX(pc.getId(),ActionCodes.ACTION_Idle));
				pc.broadcastPacketAll(new S_DoActionGFX(pc.getId(),ActionCodes.ACTION_Idle));
			}
		} catch (final Exception e) {
			_log.log(Level.SEVERE, e.getLocalizedMessage(), e);

		} finally {
			this.over();
		}
	}

}
